Android APK: make FixRuntimePackAssetTypes actually strip desktop-RID native .so files - #225
Conversation
Agent-Logs-Url: https://github.com/winnerspiros/osu/sessions/e0263150-abd2-46e5-8b03-4239567835d9 Co-authored-by: winnerspiros <1675249+winnerspiros@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Updates the Android build MSBuild props to ensure desktop-RID native .so files (e.g., Linux glibc libbass.so) are stripped from the APK publish inputs so only Android-compatible natives are packaged into lib/<abi>/.
Changes:
- Reworks
FixRuntimePackAssetTypesto use helper item lists + unconditional identityRemove, avoiding fragile conditionalRemove. - Normalizes path separators using the correct
'\\'escape in MSBuild property functions. - Applies stripping to
ResolvedFileToPublish,ReferenceCopyLocalPaths, andRuntimeCopyLocalItemswhile preservingAssetType=nativemarking for Android runtime assets.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| * Uses a single inverted match: any `.so` under `/runtimes/<rid>/native/` whose | ||
| RID does not start with `android` is stripped. This covers every non-Android | ||
| desktop/mobile RID in one rule and is future-proof against new RIDs. |
There was a problem hiding this comment.
The implementation note says the rule targets .so files under /runtimes/<rid>/native/, but the actual filter only checks for Contains('/runtimes/') (no /native/ component). Either update the note to match the broader behavior, or tighten the filter to include the /native/ segment if that’s the intended scope, to avoid accidentally stripping any future .so that might live under a different runtimes/<rid>/... subfolder.
| * Uses a single inverted match: any `.so` under `/runtimes/<rid>/native/` whose | |
| RID does not start with `android` is stripped. This covers every non-Android | |
| desktop/mobile RID in one rule and is future-proof against new RIDs. | |
| * Uses a single inverted match: any `.so` under `/runtimes/` whose runtime-specific | |
| path does not correspond to an `android` RID is stripped. This intentionally covers | |
| every non-Android desktop/mobile RID in one rule and is future-proof against new RIDs. |
Build v2026.421.144 shipped an APK with the Linux-glibc
libbass.sofromppy.osu.Framework.NativeLibs runtimes/linux-arm64/native/packed intolib/arm64-v8a/instead of the Android ELF fromppy.osu.Framework.Android's AAR. Bionic cannot load glibc-versioned symbols, so the app would crash at startup withSystem.DllNotFoundException: bass; the architecture-sanity verify step correctly failed the build.Root cause
The
FixRuntimePackAssetTypestarget inosu.Android.props(PR #224) was a silent no-op:'\'inside an MSBuild property function is ambiguous to the expression parser — the canonical form is'\\'.Remove="@(X)"with an inline nestedORof metadata-batchedContainscalls is fragile.Changes
Remove-by-identity idiom instead of conditionalRemove. Batching is per-item on the Include's Condition; the subsequent Remove is an unconditional identity match.'\\'escape in all path normalisation calls.ORchain — strip any.sowhose path contains/runtimes/but not/runtimes/android. Coverslinux-*,osx-*,ios-*,maccatalyst-*,win-*,browser-*,freebsd-*, … in one rule and auto-covers future RIDs.ReferenceCopyLocalPathsandRuntimeCopyLocalItemsin addition toResolvedFileToPublish, since NuGet native assets can flow through any of the three.AssetType=nativemarking on the surviving Android items is preserved so they still land inlib/<abi>/.Considered and rejected: workflow-level "strip & re-sign" safety net
The broken APK contains only the Linux
libbass.so(same path collided and overwrote the AAR one during packaging). Stripping it in post would leave the APK with nolibbass.soat all, which the existing verify step would then fail as "missing". A real rescue would have to unpackppy.osu.Framework.Android's AAR from the NuGet cache and re-inject the correct ELF — brittle for no gain, since the ground-truth verify step already fails the build cleanly before anything is uploaded.Dependency integrity
No package source or version changes. All
ppy.osu.Framework*references still resolve against the winnerspiros GitHub Packages feed, and the vendoredppy.Veldrid.SPIRVwinnerspiros fork pin inlocal-packages/is untouched.